import wx
from core.status_logger import LogStatus as CLogger
from core.status_logger import ProgressStatus as CProgress


class TxtCtrlLog(CLogger):
    def __init__(self, ctrl:wx.TextCtrl):
        CLogger.__init__(self)
        self.log_ctrl = ctrl
        assert isinstance(self.log_ctrl, wx.TextCtrl)

    def write(self, msg, type: CLogger.MsgType= CLogger.MsgType.DEFAULT):
        if type == CLogger.MsgType.INFO:
            self.log_ctrl.SetDefaultStyle(wx.TextAttr(wx.BLUE))
        elif type == CLogger.MsgType.WARNING:
            self.log_ctrl.SetDefaultStyle(wx.TextAttr(wx.BLUE))
        elif type == CLogger.MsgType.ERROR:
            self.log_ctrl.SetDefaultStyle(wx.TextAttr(wx.RED))
        elif type == CLogger.MsgType.IMPORTANT:
            self.log_ctrl.SetDefaultStyle(wx.TextAttr(wx.RED))
        else:
            self.log_ctrl.SetDefaultStyle(wx.TextAttr(wx.BLACK))
        self.log_ctrl.AppendText(msg)
        self.log_ctrl.SetDefaultStyle(wx.TextAttr(wx.BLACK))

    def carriage_return(self):
        lp = self.log_ctrl.GetLastPosition()
        if lp > 0:
            nl = self.log_ctrl.GetNumberOfLines()
            ll = self.log_ctrl.GetLineLength(nl-1)
            if ll > 0:
                self.log_ctrl.Remove(lp-ll, lp)

    def line_feed(self):
        self.log_ctrl.AppendText('\n')

    def backspace(self, count=1):
        lp = self.log_ctrl.GetLastPosition()
        if lp > 0:
            l = min(lp, count)
            self.log_ctrl.Remove(lp - l, lp)


class ProgressBar(CProgress):
    def __init__(self, ctrl: wx.Gauge, lbl: wx.StaticText):
        CProgress.__init__(self)
        self.gauge = ctrl
        self.label = lbl
        self.step = 1
        pass

    def set_range(self, val):
        self.gauge.SetRange(val)

    def set_step(self, val):
        if isinstance(val, int) and 0 < val < self.gauge.GetRange():
            self.step = val
        elif isinstance(val, float) and 0. < val < 1.0:
            self.step = self.gauge.GetRange() * val

    def reset_value(self):
        self.gauge.SetValue(0)
        if self.label is not None:
            self.label.SetLabelText("--.-%")

    def set_value(self, val):
        if isinstance(val, int):
            self.gauge.SetValue(val)
            if self.label is not None:
                self.label.SetLabelText("{:.1%}".format(val / self.gauge.GetRange()))
        elif isinstance(val, float):
            self.gauge.SetValue(self.gauge.GetRange()*val)
            if self.label is not None:
                self.label.SetLabelText("{:.1%}".format(val))

    def get_value(self):
        return self.gauge.GetValue()

    def increase(self, count=1):
        v = max(0,min(self.gauge.GetRange(), self.gauge.GetValue()+self.step*count))
        self.gauge.SetValue(v)
        if self.label is not None:
            self.label.SetLabelText("{:.1%}".format(v / self.gauge.GetRange()))

